package com.huan.social.github.config;

import com.huan.social.github.connect.GitHubConnectionFactory;
import com.huan.social.github.connect.GithubConnectionSignUp;
import com.huan.social.security.GithubAuthenticationSuccessHandlerSuccessHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.social.SocialAutoConfigurerAdapter;
import org.springframework.boot.autoconfigure.social.SocialWebAutoConfiguration;
import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.encrypt.Encryptors;
import org.springframework.social.config.annotation.EnableSocial;
import org.springframework.social.connect.ConnectionFactory;
import org.springframework.social.connect.ConnectionFactoryLocator;
import org.springframework.social.connect.UsersConnectionRepository;
import org.springframework.social.connect.jdbc.JdbcUsersConnectionRepository;
import org.springframework.social.connect.web.HttpSessionSessionStrategy;
import org.springframework.social.connect.web.ProviderSignInUtils;
import org.springframework.social.security.SocialAuthenticationFilter;
import org.springframework.social.security.SpringSocialConfigurer;

import javax.sql.DataSource;

/**
 * github 社交登录的自动配置
 *
 * @author huan.fu
 * @date 2018/9/27 - 17:35
 */
@Configuration
@EnableSocial
@ConditionalOnProperty(prefix = "spring.social.github", name = "provider-id")
@AutoConfigureBefore(SocialWebAutoConfiguration.class)
@AutoConfigureAfter(WebMvcAutoConfiguration.class)
public class GithubAutoAuthConfig extends SocialAutoConfigurerAdapter {

	@Autowired
	private GithubProperties githubProperties;

	@Autowired
	private DataSource dataSource;

	@Autowired
	private GithubAuthenticationSuccessHandlerSuccessHandler githubAuthenticationSuccessHandlerSuccessHandler;

	@Override
	protected ConnectionFactory<?> createConnectionFactory() {
		return new GitHubConnectionFactory(githubProperties.getProviderId(), githubProperties.getClientId(), githubProperties.getClientSecret());
	}

	@Override
	public UsersConnectionRepository getUsersConnectionRepository(ConnectionFactoryLocator connectionFactoryLocator) {
		// 第三个参数表数保存到数据库中的数据是以何种方式进行存储的，此处明文进行存储
		JdbcUsersConnectionRepository jdbcUsersConnectionRepository = new JdbcUsersConnectionRepository(dataSource, connectionFactoryLocator, Encryptors.noOpText());
		// 设置 UserConnection 表的前缀，此处不进行设置
		jdbcUsersConnectionRepository.setTablePrefix("");
		jdbcUsersConnectionRepository.setConnectionSignUp(new GithubConnectionSignUp());
		return jdbcUsersConnectionRepository;
	}

	/**
	 * 将 spring social 加入到 spring security 的过滤器链中
	 *
	 * @return
	 */
	@Bean
	public SpringSocialConfigurer springSocialConfigurer() {
		return new SpringSocialConfigurer() {
			@Override
			protected <T> T postProcess(T object) {
				SocialAuthenticationFilter filter = (SocialAuthenticationFilter) object;
				filter.setAuthenticationSuccessHandler(githubAuthenticationSuccessHandlerSuccessHandler);
				return (T) filter;
			}
		};
	}

	/**
	 * 登录帮助类
	 *
	 * @param connectionFactoryLocator
	 * @param usersConnectionRepository
	 * @return
	 */
	@Bean
	public ProviderSignInUtils providerSignInUtils(ConnectionFactoryLocator connectionFactoryLocator, UsersConnectionRepository usersConnectionRepository) {
		return new ProviderSignInUtils(new HttpSessionSessionStrategy(), connectionFactoryLocator, usersConnectionRepository);
	}
}